package com.douqu.game.core.entity.world;

import com.bean.core.buffer.ByteBuffer;
import com.douqu.game.core.config.challenge.OfficialRankConfig;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.ext.data.BaseData;
import com.douqu.game.core.entity.ext.data.challenge.OfficialRankData;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.util.LoadUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.StringUtils;
import com.douqu.game.core.util.CoreUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author wangzhenfei
 *         2017-10-19 14:16
 *         世界排行  包括竞技场和官阶战
 */
public class WorldOfficialData extends BaseData {


    /**camp  rankId  data***/
    private Map<Integer, Map<Integer,List<WorldOfficialBean>>> officialRanksMap = new ConcurrentHashMap<>();

    private Map<Integer, Map<Integer,List<WorldOfficialBean>>> yesterdayOfficialRanksMap = new ConcurrentHashMap<>();

    private long lastCopyTime;



    @Override
    public void init()
    {
        officialRanksMap.clear();
        List<OfficialRankConfig> list = DataFactory.getInstance().getDataList(DataFactory.OFFICIAL_RANK_KEY);
        List<WorldOfficialBean>  dataList;
        Map<Integer,List<WorldOfficialBean>> rankMap;
        List<String> nameDefault = null;
        for(int i = 0; i < list.size(); i++){
            rankMap = officialRanksMap.get(list.get(i).camp);
            if(rankMap == null){
                rankMap = new ConcurrentHashMap<>();
                officialRanksMap.put(list.get(i).camp, rankMap);
            }
            int index = list.get(i).id % 100;
            dataList = new CopyOnWriteArrayList<>();
            if(index < 6){
                if(index == 1){
                    nameDefault = LoadUtils.getRandomPlayerNameList(5);
                }
                WorldOfficialBean bean = new WorldOfficialBean();
                bean.setName(nameDefault.get(index - 1));
                dataList.add(bean);
            }
//            for(int j = 0; j < list.get(i).getMaxPerson(); j++){
//                //每个官阶初始化
//                dataList.add(new WorldOfficialRankBean());
//            }
            rankMap.put(index, dataList);

        }

    }


    @Override
    public void checkInit() {
        if(officialRanksMap.size() == 0)
        {
            init();
        }
    }

    @Override
    public void reset()
    {
        copyRankToYesterdayRank();
    }

    @Override
    public void checkReset() {
        if (lastCopyTime == 0)
            return;
        if(!CoreUtils.isTodayByOffset(lastCopyTime, DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR)){
            reset();
        }
    }


    @Override
    public void writeTo(ByteBuffer buffer)
    {
        buffer.writeByte(officialRanksMap.size());
        for(Map.Entry<Integer, Map<Integer, List<WorldOfficialBean>>> entry : officialRanksMap.entrySet())
        {
            buffer.writeByte(entry.getKey());

            buffer.writeByte(entry.getValue().size());

            for(Map.Entry<Integer, List<WorldOfficialBean>> entry1 : entry.getValue().entrySet())
            {
                buffer.writeShort(entry1.getKey());

                buffer.writeShort(entry1.getValue().size());

                for(WorldOfficialBean data : entry1.getValue())
                {
                    data.writeTo(buffer);
                }
            }
        }

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        buffer.writeByte(yesterdayOfficialRanksMap.size());
        for(Map.Entry<Integer, Map<Integer, List<WorldOfficialBean>>> entry : yesterdayOfficialRanksMap.entrySet())
        {
            buffer.writeByte(entry.getKey());

            buffer.writeByte(entry.getValue().size());

            for(Map.Entry<Integer, List<WorldOfficialBean>> entry1 : entry.getValue().entrySet())
            {
                buffer.writeShort(entry1.getKey());

                buffer.writeShort(entry1.getValue().size());

                for(WorldOfficialBean data : entry1.getValue())
                {
                    data.writeTo(buffer);
                }
            }
        }

        buffer.writeLong(lastCopyTime);
    }

    @Override
    public void loadFrom(ByteBuffer buffer)
    {
        officialRanksMap.clear();

        int campSize = buffer.readByte();
        Map<Integer,List<WorldOfficialBean>> campMap = null;
        List<WorldOfficialBean> datas = null;
        WorldOfficialBean data = null;
        for(int i = 0; i < campSize; i++)
        {
            int campKey = buffer.readByte();
            campMap = new ConcurrentHashMap<>();
            int idSize = buffer.readByte();
            for(int j = 0; j < idSize; j++){
                int idKey = buffer.readShort();
                datas = new CopyOnWriteArrayList<>();
                int listSize = buffer.readShort();
                for(int k = 0; k < listSize; k++){
                    data = new WorldOfficialBean();
                    data.loadFrom(buffer);
                    data.setRankId(idKey);
                    datas.add(data);
                }
                campMap.put(idKey, datas);
            }
            officialRanksMap.put(campKey, campMap);
        }

        Set<WorldOfficialBean> treeSet;
        for (Map.Entry<Integer, Map<Integer,List<WorldOfficialBean>>> entry:officialRanksMap.entrySet()){
            for (List<WorldOfficialBean> beanList:entry.getValue().values()){
                treeSet = new LinkedHashSet<>(beanList);
                beanList.clear();
                beanList.addAll(treeSet);
            }
        }
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        yesterdayOfficialRanksMap.clear();
        campSize = buffer.readByte();
        for(int i = 0; i < campSize; i++)
        {
            int campKey = buffer.readByte();
            campMap = new ConcurrentHashMap<>();
            int idSize = buffer.readByte();
            for(int j = 0; j < idSize; j++){
                int idKey = buffer.readShort();
                datas = new CopyOnWriteArrayList<>();
                int listSize = buffer.readShort();
                for(int k = 0; k < listSize; k++){
                    data = new WorldOfficialBean();
                    data.loadFrom(buffer);
                    data.setRankId(idKey);
                    datas.add(data);
                }
                campMap.put(idKey, datas);
            }
            yesterdayOfficialRanksMap.put(campKey, campMap);
        }
        for (Map.Entry<Integer, Map<Integer,List<WorldOfficialBean>>> entry:yesterdayOfficialRanksMap.entrySet()){
            for (List<WorldOfficialBean> beanList:entry.getValue().values()){
                treeSet = new LinkedHashSet<>(beanList);
                beanList.clear();
                beanList.addAll(treeSet);
            }
        }
        lastCopyTime = buffer.readLong();
    }


    /**
     * 保存前一天的排行记录
     */
    private void copyRankToYesterdayRank()
    {
        LogUtils.warn("official yesterdayRank reset start ... ");
        yesterdayOfficialRanksMap.clear();
        for(Map.Entry<Integer, Map<Integer, List<WorldOfficialBean>>> entry : officialRanksMap.entrySet())
        {
            Map<Integer, List<WorldOfficialBean>> copyIntegerListMap = new ConcurrentHashMap<>();
            for (Map.Entry<Integer, List<WorldOfficialBean>> entry1 : entry.getValue().entrySet())
            {
                List<WorldOfficialBean> copyWorldOfficialRankDatas = new CopyOnWriteArrayList<>();
                for(WorldOfficialBean data : entry1.getValue()){
                    copyWorldOfficialRankDatas.add(new WorldOfficialBean(data.getObjectIndex()));
                }
                copyIntegerListMap.put(entry1.getKey(), copyWorldOfficialRankDatas);
            }
            yesterdayOfficialRanksMap.put(entry.getKey(), copyIntegerListMap);
        }
//        for (Integer camp : officialRanksMap.keySet()) {
//            Map<Integer, List<WorldOfficialBean>> copyIntegerListMap = new ConcurrentHashMap<>();
//            Map<Integer, List<WorldOfficialBean>> integerListMap = officialRanksMap.get(camp);
//            for (Integer id : integerListMap.keySet()) {
//                List<WorldOfficialBean> copyWorldOfficialRankDatas = new CopyOnWriteArrayList<>();
//                List<WorldOfficialBean> worldOfficialRankDatas = integerListMap.get(id);
//                for(WorldOfficialBean data : worldOfficialRankDatas){
//                    copyWorldOfficialRankDatas.add(new WorldOfficialBean(data.getObjectIndex()));
//                }
//                copyIntegerListMap.put(id, copyWorldOfficialRankDatas);
//            }
//            yesterdayOfficialRanksMap.put(camp, copyIntegerListMap);
//        }
        lastCopyTime = DataFactory.currentTime;
    }

    /**
     * 根据自己的阵营获取自己的官阶战信息
     * @param player
     * @return
     */
    public WorldOfficialBean getRankInfoByObjectIndex(Player player){
        int camp = player.camp;
        String objectIndex = player.getObjectIndex();
        WorldOfficialBean bean = null;
        Map<Integer,List<WorldOfficialBean>> idsMap = officialRanksMap.get(camp);
        if(idsMap != null)
        {
            OfficialRankData officialRankData = player.getOfficialData();
            List<WorldOfficialBean> rankList = idsMap.get(officialRankData.getCurRankId());
            if(rankList != null)
            {
                int position = rankList.indexOf(new WorldOfficialBean(objectIndex));
                if(position >= 0){
                    bean = rankList.get(position);
//                bean.setRankId(id);
//                bean.setPosition(position);
                }
            }
        }
        return bean;

    }


    /**
     * 根据自己的阵营获取自己的昨日官阶战信息
     * @param player
     * @return
     */
    public WorldOfficialBean getYesterdayRankInfoByObjectIndex(Player player){
        int camp = player.camp;
        String objectIndex = player.getObjectIndex();
        WorldOfficialBean bean = null;
        Map<Integer,List<WorldOfficialBean>> idsMap = yesterdayOfficialRanksMap.get(camp);
        if(idsMap != null)
        {
            for(Map.Entry<Integer, List<WorldOfficialBean>> entry : idsMap.entrySet())
            {
                int position = entry.getValue().indexOf(new WorldOfficialBean(objectIndex));
                if(position >= 0){
                    bean = entry.getValue().get(position);
                    bean.setRankId(entry.getKey());
                    bean.setPosition(position);
                    break;
                }
            }
        }
        return bean;

    }

    /**
     * 删除错误的玩家
     * @param
     * @return
     */
    public void deleteRankInfo(int camp, int targetRankId, String objectIndex){
        if(StringUtils.isNullOrEmpty(objectIndex)){
            return;
        }
        Map<Integer,List<WorldOfficialBean>> idsMap = officialRanksMap.get(camp);
        if(idsMap != null)
        {
            List<WorldOfficialBean> rankList = idsMap.get(targetRankId);
            if(rankList != null)
            {
               for(WorldOfficialBean officialBean : rankList){
                   if(objectIndex.equals(officialBean.getObjectIndex())){
                       officialBean.setObjectIndex("");
                       break;
                   }
               }
            }
        }

    }

    /**
     * 获取目标官阶指定位置的排行对象
     * @param officialRankId
     * @param position
     * @return
     */
    public WorldOfficialBean getTargetPositionPlayer(int camp, int officialRankId, int position){
        WorldOfficialBean bean = null;
        try {
            bean = officialRanksMap.get(camp).get(officialRankId).get(position);
        } catch (Exception e) {
            LogUtils.error("获取目标官阶指定位置的排行对象不存在");
        }

        return bean;

    }

    /**
     * 获取前五位的玩家或者npc
     * @param player
     * @return
     */
    public List<WorldOfficialBean> getTop5Player(Player player){
        int camp = player.camp;
        List<WorldOfficialBean> resultList = null;
        WorldOfficialBean rankBean;
        Map<Integer,List<WorldOfficialBean>> idsMap = officialRanksMap.get(camp);
        if(idsMap  != null){
            resultList = new ArrayList<>();
            for(int i = 1 ; i < 6; i++){
                rankBean = new WorldOfficialBean();
                rankBean.setRankId(i);
                List<WorldOfficialBean> list = idsMap.get(i);
                if(list.size() != 0){
                    if(StringUtils.isNullOrEmpty(list.get(0).getObjectIndex()) &&
                            StringUtils.isNullOrEmpty(list.get(0).getName())){
                        list.get(0).setName(LoadUtils.getRandomPlayerName());
                    }
                    rankBean.setObjectIndex(list.get(0).getObjectIndex());
                    rankBean.setName(list.get(0).getName());
                }
                resultList.add(rankBean);
            }
        }

        return resultList;

    }





    /**
     * 根据官阶id获取此官阶最多四个人信息
     * @param targetRankId
     * @return
     */
    public List<WorldOfficialBean> getTargetRankPlayer(Player player, int targetRankId){
        List<WorldOfficialBean> resultList = null;
        int camp = player.camp;
        Map<Integer,List<WorldOfficialBean>> idsMap = officialRanksMap.get(camp);
        if(idsMap  != null){
            List<WorldOfficialBean> rankList = idsMap.get(targetRankId);
            if(rankList != null){
                resultList = new ArrayList<>();
                //获取对应官阶最大人数
                OfficialRankConfig config = DataFactory.getInstance().getGameObject(DataFactory.OFFICIAL_RANK_KEY, targetRankId + 100 * camp);
                //自己所在官阶
                WorldOfficialBean myRank = getRankInfoByObjectIndex(player);
                int offset = 0;
                if(myRank != null && myRank.getRankId() == targetRankId){ //自己的所在的官阶就是目标官阶
                    offset = 1;
                    resultList.add(myRank);
                }
                int maxReturnNum = Math.min(config.maxPerson - offset, 4 - offset);//最大返回人数
                 List<Integer> indexList = CoreUtils.getRandomInteger(maxReturnNum, config.maxPerson);
                int size = indexList == null ? 0 : indexList.size();
                for(int i = 0; i < size; i++){
                    WorldOfficialBean rankBean;
                    if(indexList.get(i) < rankList.size()) {
                        rankBean = rankList.get(indexList.get(i));
                        rankBean.setPosition(indexList.get(i));
                    }else {//随机的位置已经超出该官阶的已有人员，添加
                        //首先找到最老的未被占用的npc位置
                         int index = getMinEmptyNpcIndex(rankList, indexList);
                        if(index != -1 ){//
                            rankBean = rankList.get(index);
                            rankBean.setPosition(index);
                            indexList.set(i, index);
                        }else{
                            rankBean = new WorldOfficialBean();
                            rankBean.setPosition(rankList.size());
                            indexList.set(i, rankList.size());
                            rankList.add(rankBean);
                        }
                    }
                    rankBean.setRankId(targetRankId);
                    resultList.add(rankBean);
                }

            }
        }

        return resultList;
    }


    public int getMinEmptyNpcIndex(List<WorldOfficialBean> rankList, List<Integer> indexList){
        int index = -1;
        int size = rankList.size();
        WorldOfficialBean rankBean;
        for(int i = 0; i < size; i++){
            rankBean = rankList.get(i);
            if(StringUtils.isNullOrEmpty(rankBean.getObjectIndex()) && !indexList.contains(i)&&
                    !rankBean.isBattle()){// 有空的npc并且不在随机列表里面且不在被挑战
                index = i;
                break;
            }
        }
        return index;
    }

    public void removePlayer(Player player)
    {
        Map<Integer,List<WorldOfficialBean>> idsMap = officialRanksMap.get(player.camp);
        if(idsMap != null){
            OfficialRankData officialRankData = player.getOfficialData();
            if(officialRankData.getCurRankId() == 0)
                return;

            List<WorldOfficialBean> rankList = idsMap.get(officialRankData.getCurRankId());
            int position = rankList.indexOf(new WorldOfficialBean(player.getObjectIndex()));
            if(position >= 0){
                rankList.remove(position);
            }
        }

    }


    @Override
    public String toString() {
//        StringBuilder str = new StringBuilder();
//        for(Integer key : officialRanksMap.keySet())
//        {
//            str.append("阵营:" + key + "\n");
//            Map<Integer,List<WorldOfficialRankBean>> campMap = officialRanksMap.get(key);
//            for(Integer rank : campMap.keySet())
//            {
//                str.append("官阶ID:" + rank + "\n");
//                List<WorldOfficialRankBean> list = campMap.get(rank);
//                for(WorldOfficialRankBean bean : list)
//                {
//                    str.append("官阶信息:" + bean + "\n");
//                }
//            }
//        }
        return officialRanksMap.toString();
    }

    public Map<Integer, Map<Integer, List<WorldOfficialBean>>> getOfficialRanksMap() {
        return officialRanksMap;
    }

    public void setOfficialRanksMap(Map<Integer, Map<Integer, List<WorldOfficialBean>>> officialRanksMap) {
        this.officialRanksMap = officialRanksMap;
    }

    public void clear()
    {
        officialRanksMap.clear();
    }

}

